package kortmann.rene.leo.service;

import java.io.IOException;
import java.util.LinkedList;
import java.util.List;

import kortmann.rene.leo.exceptions.ForbiddenException;
import kortmann.rene.leo.exceptions.LeoNotFoundException;
import kortmann.rene.leo.factories.LeoFactory;
import kortmann.rene.leo.model.LEO;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.ParseException;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;

class LeoApi 
{
	private static final String LEOS_URL = "http://localhost:91/leo/service.php/api/v1/leos";
	
	public LEO getLEO(int inID, HttpClient client, HttpContext localContext) throws LeoNotFoundException, ForbiddenException
	{
		LEO result = new LEO();
		
		HttpGet httpGet = null;
		
		try
		{
			String url = String.format("%s/%s", LEOS_URL, inID);
			httpGet = new HttpGet(url);
			
			HttpResponse response = client.execute(httpGet, localContext);
		
			StatusLine sl = response.getStatusLine();
			
			if(sl.getStatusCode() == 404)
			{
				throw new LeoNotFoundException(sl.getReasonPhrase());
			}
			else if(sl.getStatusCode() == 403)
			{
				throw new ForbiddenException(sl.getReasonPhrase());
			}
			
			HttpEntity entity = response.getEntity();
					
			if(entity != null)
			{
				result = LeoFactory.GetLeoFromJson(EntityUtils.toString(entity));
			}
		} catch (ParseException e) {
			result = null;
			
			e.printStackTrace();
		} catch (IOException e) {
			result = null;
			
			e.printStackTrace();
		}
		finally
		{
			if(httpGet != null)
			{
				httpGet.releaseConnection();
				httpGet = null;
			}
		}
		
		return result;
	}
	
	public List<LEO> getAllLEOs(HttpClient client, HttpContext localContext) throws LeoNotFoundException, ForbiddenException
	{
		List<LEO> result = new LinkedList<LEO>();
		
		HttpGet httpGet = null;
		
		try
		{
			String url = LEOS_URL;
			httpGet = new HttpGet(url);
			
			HttpResponse response = client.execute(httpGet, localContext);
		
			StatusLine sl = response.getStatusLine();
			
			if(sl.getStatusCode() == 404)
			{
				throw new LeoNotFoundException(sl.getReasonPhrase());
			}
			else if(sl.getStatusCode() == 403)
			{
				throw new ForbiddenException(sl.getReasonPhrase());
			}
			
			HttpEntity entity = response.getEntity();
					
			if(entity != null)
			{
				JSONParser parser = new JSONParser();

				try
				{
					JSONArray array = (JSONArray)parser.parse(EntityUtils.toString(entity));
					
					for(int i = 0; i < array.size(); i++)
					{
						result.add(LeoFactory.GetLeoFromJson(((JSONObject)array.get(i)).toJSONString()));
					}
				}
				catch(org.json.simple.parser.ParseException pe)
				{
					pe.printStackTrace();
				}
			}
		} catch (ParseException e) {
			result = null;
			
			e.printStackTrace();
		} catch (IOException e) {
			result = null;
			
			e.printStackTrace();
		}
		finally
		{
			if(httpGet != null)
			{
				httpGet.releaseConnection();
				httpGet = null;
			}
		}
		
		return result;
	}
	
	public LEO updateLEO(LEO inLEO, HttpClient client, HttpContext localContext) throws LeoNotFoundException, ForbiddenException
	{
		LEO result = null;
		
		HttpPut httpPut = null;
		
		try
		{
			String url = String.format("%s/%s", LEOS_URL, inLEO.getId());;
			httpPut = new HttpPut(url);
			
			ByteArrayEntity stringEntity = new ByteArrayEntity(LeoFactory.getJsonFromLeo(inLEO).getBytes("UTF-8"));
			httpPut.setEntity(stringEntity);
			
			httpPut.addHeader("Content-Type", "application/json");
			
			HttpResponse response = client.execute(httpPut, localContext);
			
			StatusLine sl = response.getStatusLine();
			
			if(sl.getStatusCode() == 404)
			{
				throw new LeoNotFoundException(sl.getReasonPhrase());
			}
			else if(sl.getStatusCode() == 403)
			{
				throw new ForbiddenException(sl.getReasonPhrase());
			}
			
			HttpEntity entity = response.getEntity();
					
			if(entity != null)
			{
				result = LeoFactory.GetLeoFromJson(EntityUtils.toString(entity));
			}
		} catch (ParseException e) {
			result = null;
			
			e.printStackTrace();
		} catch (IOException e) {
			result = null;
			
			e.printStackTrace();
		}
		finally
		{
			if(httpPut != null)
			{
				httpPut.releaseConnection();
				httpPut = null;
			}
		}
		
		return result;
	}
	
	public boolean deleteLEO(String inID, HttpClient client, HttpContext localContext) throws LeoNotFoundException, ForbiddenException
	{	
		boolean result = false;
		
		HttpDelete httpDelete = null;
		
		try
		{
			String url = String.format("%s/%s", LEOS_URL, inID);
			httpDelete = new HttpDelete(url);
			
			HttpResponse response = client.execute(httpDelete, localContext);
		
			StatusLine sl = response.getStatusLine();
			
			if(sl.getStatusCode() == 404)
			{
				throw new LeoNotFoundException(sl.getReasonPhrase());
			}
			else if(sl.getStatusCode() == 403)
			{
				throw new ForbiddenException(sl.getReasonPhrase());
			}
			else 
				result = true;
		} catch (ClientProtocolException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		finally
		{
			if(httpDelete != null)
			{
				httpDelete.releaseConnection();
				httpDelete = null;
			}
		}
		
		return result;
	}
	
	public LEO createLEO(String inJsonString, HttpClient client, HttpContext localContext) throws LeoNotFoundException, ForbiddenException
	{
		LEO result = new LEO();
		
		HttpPost httpPost = null;
		
		try
		{
			String url = LEOS_URL;
			httpPost = new HttpPost(url);
			
			ByteArrayEntity stringEntity = new ByteArrayEntity(inJsonString.getBytes("UTF-8"));
			httpPost.setEntity(stringEntity);
			
			httpPost.addHeader("Content-Type", "application/json");
			
			HttpResponse response = client.execute(httpPost, localContext);
			
			StatusLine sl = response.getStatusLine();
			
			if(sl.getStatusCode() == 404)
			{
				throw new LeoNotFoundException(sl.getReasonPhrase());
			}
			else if(sl.getStatusCode() == 403)
			{
				throw new ForbiddenException(sl.getReasonPhrase());
			}
			
			HttpEntity entity = response.getEntity();
					
			if(entity != null)
			{
				result = LeoFactory.GetLeoFromJson(EntityUtils.toString(entity));
			}
		} catch (ParseException e) {
			result = null;
			
			e.printStackTrace();
		} catch (IOException e) {
			result = null;
			
			e.printStackTrace();
		}
		finally
		{
			if(httpPost != null)
			{
				httpPost.releaseConnection();
				httpPost = null;
			}
		}
		
		return result;
	}
}
